package com.junjie.checkin.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.junjie.checkin.entity.Enum.PointRecordTypeEnum;
import com.junjie.checkin.entity.TPointRecord;
import com.junjie.checkin.entity.TUser;
import com.junjie.checkin.exception.*;
import com.junjie.checkin.mapper.ActivityHistoryMapper;
import com.junjie.checkin.mapper.PointRecordMapper;
import com.junjie.checkin.mapper.UserMapper;
import com.junjie.checkin.request.user.*;
import com.junjie.checkin.response.*;
import com.junjie.checkin.response.admin.*;
import com.junjie.checkin.response.front.UserFrontResponse;
import com.junjie.checkin.response.pointRecord.PointRecordResponse;
import com.junjie.checkin.security.service.impl.JwtServiceImpl;
import com.junjie.checkin.utils.DateTimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author lwlianghehe@gmail.com
 * @date 2025/05/28 17:42
 */
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtServiceImpl jwtService;
    @Autowired
    private PasswordEncoder encoder;
    @Autowired
    PointRecordMapper pointRecordMapper;
    @Autowired
    private ActivityHistoryMapper activityHistoryMapper;

    /**
     * 根据id查询用户
     * @param id 查询的用户ID
     * @return 用户信息
     */
    public UserResponse getUserById(Integer id) {
        // 检查用户是否存在
        TUser user = userMapper.selectById(id);
        if(user == null){
            throw new ResourceNotFountException();
        }
        // 填充数据
        UserResponse userResponse = new UserResponse();
        BeanUtils.copyProperties(user,userResponse);
        return userResponse;
    }

    /**
     * 获取当前用户的信息
     * @param token 登录令牌
     * @return 用户信息
     */
    public UserFrontResponse getCurrentUserInfo(String token){
        Integer id = jwtService.analyzeToken(token).getUser().getId();
        TUser user = userMapper.selectById(id);
        UserFrontResponse userResponse = new UserFrontResponse();
        BeanUtils.copyProperties(user,userResponse);
        userResponse.setUserId(id);
        return userResponse;
    }

    /**
     * 修改当前用户信息
     * @param userFrontRequest 用户信息
     * @param token 登录令牌
     */
    public void updateCurrentUserInfo(UserFrontRequest userFrontRequest, String token){
        Integer id = jwtService.analyzeToken(token).getUser().getId();
        TUser user = userMapper.selectById(id);
        if (userFrontRequest.getNickname()!=null|| userFrontRequest.getNickname().isEmpty()){
            user.setNickname(userFrontRequest.getNickname());
        }
        if (userFrontRequest.getAvatar()!=null|| userFrontRequest.getAvatar().isEmpty()){
            user.setAvatar(userFrontRequest.getAvatar());
        }
        if (userFrontRequest.getPassword()!=null|| userFrontRequest.getPassword().isEmpty()){
            user.setPassword(encoder.encode(userFrontRequest.getPassword()));
        }
        userMapper.updateById(user);
    }

    /**
     * 获取用户列表
     * @param userPageRequest  用户分页信息
     * @return 统一响应,返回用户分页列表
     */
    public PageResult<UserResponse> getUsers(UserPageRequest userPageRequest) {
        PageHelper.startPage(userPageRequest.getPage(),userPageRequest.getPageSize());
        Page<UserResponse> page = userMapper.pageQueryUser(userPageRequest);
        return new PageResult<UserResponse>(page.getTotal(),page.getResult());
    }

    /**
     * 获取学生列表
     * @param userPageRequest 用户分页信息
     * @return 统一响应,返回学生分页列表
     */
    public PageResult<UserResponse> getStudents(UserPageRequest userPageRequest) {
        PageHelper.startPage(userPageRequest.getPage(),userPageRequest.getPageSize());
        Page<UserResponse> page = userMapper.pageQueryStudent(userPageRequest);
        return new PageResult<UserResponse>(page.getTotal(),page.getResult());
    }


    /**
     * 添加管理员
     * @param userRequest 添加的用户信息
     */
    public UserResponse insertAdmin(UserRequest userRequest, String token) {
        String username = jwtService.analyzeToken(token).getUsername();
        return this.insertUser(userRequest,username, (byte) 1);
    }

    /**
     * 添加学生
     * @param userRequest 添加的学生信息
     * @param token 添加的学生的用户令牌
     * @return 添加的学生信息
     */

    public UserResponse insertStudent(UserRequest userRequest,String token){
        String username = jwtService.analyzeToken(token).getUsername();
        return this.insertUser(userRequest, username, (byte) 0);
    }


    /**
     * 添加用户的逻辑
     * @param userRequest 添加用户的信息
     * @param username 添加用户的用户名
     * @param role 添加用户的角色
     * @return 添加用户的结果
     */
    private UserResponse insertUser (UserRequest userRequest,String username,byte role){
        TUser u = userMapper.getUserByUsername(userRequest.getUsername());
        if (!Objects.isNull(u)){
            throw new UserAlreadyExistsException();
        }
        TUser user = new TUser();
        BeanUtils.copyProperties(userRequest,user);
        //设置创建时间
        user.setCreateTime(new Date());
        //设置用户类型
        user.setRole((byte)role);
        //密码加密
        String encodePass = encoder.encode(userRequest.getPassword());
        user.setPassword(encodePass);
        user.setCreateBy(username);
        // 设置积分
        if (role == 0){
            user.setScore(0);
        }
        userMapper.insert(user);
        System.out.println(user);
        // 封装返回结果
        UserResponse userResponse =null;
        if (role==1){
            userResponse = new UserResponse();
        }
        else {
            userResponse = new StudentResponse();
        }

        BeanUtils.copyProperties(user,userResponse);
        return userResponse;
    }

    /**
     * 修改用户
     * @param userRequest 修改的用户信息
     * @param token 当前用户的token
     */
    public void updateUser(Integer id,UserUpdateRequest userRequest, String token) {
        TUser user = userMapper.selectById(id);
        if (Objects.isNull(user)){
            throw  new ResourceNotFountException();
        }
        if (!Objects.isNull(userRequest.getNickname())&& !userRequest.getNickname().isEmpty()){
            user.setNickname(userRequest.getNickname());
        }
        if (!Objects.isNull(userRequest.getAvatar())&& !userRequest.getAvatar().isEmpty()){
            user.setAvatar(userRequest.getAvatar());
        }
        if (!Objects.isNull(userRequest.getPassword())&& !userRequest.getPassword().isEmpty()){
            user.setPassword(encoder.encode(userRequest.getPassword()));
        }
        user.setUpdateBy(jwtService.getUserName(token));
        userMapper.updateById(user);
    }


    /**
     * 删除用户
     * @param id 删除的用户ID
     */
    public void deleteUser(Integer id,String token) {
        TUser user = jwtService.analyzeToken(token).getUser();
        // 校验, 不能删除自己 TODO 这边需要做逻辑删除,由于有些外键关联,所以不能直接删除
        if (Objects.equals(user.getId(), id)){
            throw new DeleteOwnException();
        }
        userMapper.deleteById(id);
    }


    /**
     * 查询积分前五用户
     * @param limit 查询数量
     * @return 用户数据
     */
    public List<UserFrontResponse> getLatestUsers(int limit) {
        return userMapper.selectLatestUsers(limit);
    }

    /**
     * 管理员修改用户积分
     * @param id 修改用户ID
     * @param userScoreUpdateRequest 修改积分信息
     * @param token 当前用户令牌
     */

    public UserScoreUpdateResponse updateUserScore(Integer id, UserScoreUpdateRequest userScoreUpdateRequest, String token) {
        TUser updateUser = jwtService.analyzeToken(token).getUser();
        TUser user = userMapper.selectById(id);
        // 检查用户是否存在
        if (Objects.isNull(user)){
            throw  new ResourceNotFountException();
        }
        // 检查用户角色,如果该用户是管理员,则不允许修改积分
        if (user.getRole() ==1 ){
            throw new OperationsBeyondPermissionException();
        }
        // 更新用户积分数据
        TPointRecord pointRecord = new TPointRecord();
        pointRecord.setUserId(id);
        pointRecord.setRelatedType(PointRecordTypeEnum.MANUAL);
        // 判断是否为添加积分
        int updateScore = 0;
        if (userScoreUpdateRequest.getIncrease()){
            updateScore = userScoreUpdateRequest.getScore();
        }
        else {
            // 检查积分是否充足
            if (user.getScore() < userScoreUpdateRequest.getScore()){
                throw new PointsDeductionException();
            }
            updateScore = -userScoreUpdateRequest.getScore();
        }

        int totalScore = user.getScore()+updateScore;
        pointRecord.setChangePoint(updateScore);
        pointRecord.setRemark(userScoreUpdateRequest.getRemark());
        pointRecord.setCreateBy(updateUser.getUsername());
        pointRecord.setRelatedId(updateUser.getId());
        pointRecord.setTotalPoint(totalScore);
        // 捕获事务异常,出现异常回滚
        try {
            pointRecordMapper.insert(pointRecord);
            user.setScore(totalScore);
            userMapper.updateById(user);
        }catch (Exception e){
            throw e;
        }

        UserResponse userResponse = new StudentResponse();
        PointRecordResponse pointRecordResponse =new PointRecordResponse();
        BeanUtils.copyProperties(user,userResponse);
        BeanUtils.copyProperties(pointRecord,pointRecordResponse);
        pointRecordResponse.setCreateTime(DateTimeFormat.dateToString(pointRecord.getCreateTime()));

        return new UserScoreUpdateResponse(userResponse,pointRecordResponse);

    }


    /**
     * 获取前台用户排行榜
     * @param userPageRequest
     * @return
     */
    public PageResult<UserFrontResponse> getPageLatestUsers(UserPageRequest userPageRequest) {
        PageHelper.startPage(userPageRequest.getPage(),userPageRequest.getPageSize());
        Page<UserFrontResponse> page = userMapper.getPageLatestUsers(userPageRequest);

        return new PageResult<>(page.getTotal(),page.getResult());
    }

    /**
     * 获取用户积分
     * @param id
     * @return
     */
    public UserPointsResponse getUserPoints(Integer id) {

        UserPointsResponse userPointsResponse = userMapper.getUserPoints(id);
        return userPointsResponse;
    }

    /**
     * 获取用户积分详情
     * @param id
     * @return
     */
    public UserPointsDetailsResponse getUserPointsDetails(Integer id) {
        UserPointsDetailsResponse response = new UserPointsDetailsResponse();
        //获取用户累计获得积分
        Integer earnPoints = pointRecordMapper.getUserEarnPoints(id);
        //获取用户累计失去积分
        Integer losePoints = pointRecordMapper.getUserLosePoints(id);
        //获取用户参与活动数
        Integer joinActivity = activityHistoryMapper.getJoinActivity(id);
        //获取用户已完成活动数
        Integer overActivity = activityHistoryMapper.getOverActivity(id);
        //获取用户进行中的活动数
        Integer notStartedActivity = activityHistoryMapper.getNotStartedActivity(id);
        //获取用户未完成的活动数
        Integer unfinishedActivity = activityHistoryMapper.getUnfinishedActivity(id);

        return UserPointsDetailsResponse.builder()
                .notStartedActivity(notStartedActivity)
                .earnPoints(earnPoints)
                .joinActivity(joinActivity)
                .losePoints(losePoints)
                .overActivity(overActivity)
                .unfinishedActivity(unfinishedActivity)
                .build();
    }


}
